/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package schoolbank;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;

/**
 *
 * @author meydlo
 */
public class SchoolBank {

    private static HashMap<String, User> users = new HashMap<String, User>();    
//    private static Controller c = new Controller();
    
    /***************************************************************
     * TOP  LEVEL
     **************************************************************/
    
    public static void main(String[] args) {
        String text;
        BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Welcome in SchoolBank");
        do{
            try{
                do{
                    System.out.print(">");
                    text = bufferRead.readLine();
                    args = text.split("\\s");
                
                    switch(args[0]){
                        case "user":
                            manageUser(args);
                            break;
                        case "account":
                            manageAccount(args);
                            break;
                        case "list":
                            System.out.println("Current users: "+ListUsers());
                            break;
                        case "help":
                            if(args.length > 1){
                                if(args[1].equals("user"))
                                    printUserHelp();
                                else if(args[1].equals("account"))
                                    printAccountHelp();
                            }
                            else
                                printHelp();
                            break;
                        default:
                            printHelp();
                            break;
                    }
                }while(!args[0].equals("exit"));
            }
            catch(IOException e)
            {
                System.err.println(e.getMessage());
            }
            catch(Exception e)
            {
                System.err.println("Exception: "+e.getMessage());
            }
        }while(!args[0].equals("exit"));
        System.out.println("Bye");
    }
    
    /***************************************************************
     * MEDIUM LEVEL 
     **************************************************************/
    
    public static void manageUser(String[] args)
    {
        //min: 1 user, 2 delete, 3 userID
        if(args.length < 3){
            System.out.println("syntax: user [create/read/delete] userID");
            return;
        }
        
        switch(args[1]){
            case "create":
                createUser(args[2]);
                break;
            case "read":
                readUser(args[2]);
                break;
//            case "update":
//                updateUser(args[2], args[3]);
//                break;
            case "delete":
                deleteUser(args[2]);
                break;
            default:
                System.out.println("unknown command: "+args[1]);
                break;
        }
    }
    
    public static void manageAccount(String[] args)
    {        
        // min: 1 account, 2 delete, 3 userID, 4 accountID
        if(args.length < 4){
            System.out.println("min syntax: account "
                    + "[create/read/delete/withdraw/deposit]"
                    + " userID accountID");
            return;
        }
            
            
        switch(args[1]){
            case "create":
                if(args.length>4)
                {
                    System.out.println(
                            users.get(args[2]).createAccount(args[3], args[4]));
                }else{
                    System.out.println("syntax: account create userID accountID accountType");
                }
                break;
            case "read":
                if(args.length>3)
                {
                    System.out.println(users.get(args[2]).readAccount(args[3]));
                }else{
                    System.out.println("syntax: account read userID accountID");
                }
                break;
            case "withdraw":
                if(args.length>4){
                    try{
                        double wAmount = Double.parseDouble(args[4]);
                        System.out.println(users.get(args[2]).withdraw(args[3], wAmount));
                    }catch(Exception e){
                        System.out.println(e.getMessage());
                    }
                }else{
                    System.out.println("syntax: account withdraw userID accountID amount");
                }
                break;
            case "deposit":
                if(args.length > 4){
                    try{
                        double dAmount = Double.parseDouble(args[4]);
                        System.out.println(users.get(args[2]).deposit(args[3], dAmount));
                    }catch(Exception e){
                        System.out.println(e.getMessage());
                    }
                }else{
                    System.out.println("syntax: account deposit userID accountID amount");
                }
                break;
            case "delete":
                if(args.length>3)
                {
                    System.out.println(users.get(args[2]).deleteAccount(args[3]));
                }else{
                    System.out.println("syntax: account delete userID accountID");
                }
                break;
            default:
                System.out.println("unknown command: "+args[1]);
                break;
        }
    }
    
    /***************************************************************
     * LOW LEVEL
     **************************************************************/

    ///////////////////////////////////////////////////// USER MANAGINg below
    public static void createUser(String userID)
    {        
        if(isUser(userID))
        {
            System.out.println("user \""+userID+"\" already exists");
        }
        else{
            User user = new User(userID);
            users.put(userID, user);
            
            System.out.println("user \""+userID+"\" successfully created: " +
                    (users.get(userID) != null));
        }
    }
    
    public static void readUser(String userID)
    {
        //guards
         if(!isUser(userID))
         {
            System.out.println("user \""+userID+"\" does not exists");
            return;
         }
         
         //code
        String returnVal = "\""+userID+"\"'s user accounts:";
        // set iterator to iterate accounts
        Iterator<String> it = users.get(userID).getAccounts().keySet().iterator();
        
        while(it.hasNext()){        
            returnVal = returnVal + "\n\t" +it.next() ;
        }
        System.out.println(returnVal);
    }
    
    // death code in case of not possibly change userID
    public static void updateUser(String oldUserID, String newUserID)
    {        
        //guards
        if(isUser(newUserID))
        {                    // new user_id already exists
            System.out.println("user \""+newUserID+"\" already exists");
            return;
        }
        else if(!isUser(oldUserID))
        {              // old user id does not exists
            System.out.println("user \""+oldUserID+"\" not found");
            return;
        }

        // code
        User u = users.get(oldUserID);              // create instance of user
        u.setUserID(newUserID);                     // set new user ID
        users.remove(oldUserID);                    // remove user from map
        users.put(newUserID, u);                    // add updated instance 
                
        if(users.get(newUserID) != null && 
                users.get(oldUserID) == null)
        {
            System.out.println("user \""+oldUserID+"\" was updated to \""+
                        newUserID+"\"");
        }
        else{
            System.out.println("unable to change user");
        }
    }
        
    public static void deleteUser(String userID)
    {           
        if(!isUser(userID))
        {
            System.out.println("user \""+userID+"\" does not exist");
        }
        else{
            users.remove(userID);                       // remove user

            System.out.println("user \""+userID+"\" "
                            + "was successfully deleted: "+(!isUser(userID)));
        }
    }
    
    public static String ListUsers()
    {
        Iterator<String> it = users.keySet().iterator();
        String result = "";
        while(it.hasNext()){
            result = "\n\t" + it.next() + result;
        }
        
        return result;
    }
    
    /***************************************************************
     * EXtra
     **************************************************************/
    
    protected static boolean isUser(String userID){
        return users.containsKey(userID);
    }
        
    /***************************************************************
     * PRINTOUT HELPS
     **************************************************************/
    
    public static void printHelp()
    {
        System.out.println("help additions:"
                + "\n\t help user"
                + "\n\t help account");
        printUserHelp();
        printAccountHelp();
        System.out.println("to exit: \"exit\"");
    }
    
    public static void printUserHelp(){
        System.out.println("user examples:"
                + "\n\t user [create/read/delete] userID"
                + "\n\t user update oldUserID newUserID");
    }
    
    public static void printAccountHelp(){
         System.out.println("account examples:"
                + "\n\t account [create/read/delete]  userID accountID"
                 + "\n\t account [deposit/withdraw] userID accountID amount");
    }
    
    
    /***************************************************************
     * GETTERS 4 test
     **************************************************************/
    
    public static User getUser(String userID)
    {
        return users.get(userID);
    }
}
